package com.hzw.saas.service.chat.listener;

import cn.hutool.core.collection.CollectionUtil;
import com.hzw.saas.api.chat.IChatEventService;
import com.hzw.saas.api.chat.IChatGroupService;
import com.hzw.saas.api.chat.IChatUserGroupService;
import com.hzw.saas.api.chat.bo.ChatEventBO;
import com.hzw.saas.api.chat.bo.ChatUserGroupBO;
import com.hzw.saas.api.chat.bo.SingleGroupBO;
import com.hzw.saas.api.group.bo.GroupBo;
import com.hzw.saas.api.group.event.*;
import com.hzw.saas.common.util.MapperUtil;
import com.hzw.saas.common.util.SnowFlakeUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
@AllArgsConstructor
@Order(1)
public class GroupListener {

    @Autowired
    private IChatGroupService chatGroupService;

    @Autowired
    private IChatUserGroupService chatUserGroupService;

    @Autowired
    private IChatEventService chatEventService;

    /**
     * 创建群组监听器
     * @param createEvent
     */
    @Transactional
    @EventListener(GroupCreateEvent.class)
    public void createGroup(GroupCreateEvent createEvent){
        GroupBo groupBo = createEvent.getGroupBo();
        SingleGroupBO map = MapperUtil.nf().map(groupBo, SingleGroupBO.class);
        ArrayList<SingleGroupBO> singleGroupBOS = new ArrayList<>();
        singleGroupBOS.add(map);
        chatGroupService.addGroup(groupBo.getOwnerId(),singleGroupBOS,2);
        //群主自动进群
        ChatUserGroupBO chatUserGroupBO = new ChatUserGroupBO();
        chatUserGroupBO.setUserId(createEvent.getGroupBo().getOwnerId());
        chatUserGroupBO.setGroupId(createEvent.getGroupBo().getGroupId());
        chatUserGroupBO.setPermission(1);
        chatUserGroupBO.setGroupType(2);
        ArrayList<ChatUserGroupBO> chatUserGroupBOS = new ArrayList<>();
        chatUserGroupBOS.add(chatUserGroupBO);
        chatUserGroupService.saveBatch(chatUserGroupBOS);
        //群主加群事件
        ChatEventBO chatEventBO = new ChatEventBO();
        chatEventBO.setEventType(25);
        chatEventBO.setEventDetail(createEvent.getGroupBo().getOwnerId()+ "joined" + createEvent.getGroupBo().getGroupId());
        chatEventBO.setSourceId(createEvent.getGroupBo().getOwnerId());
        chatEventBO.setTargetGroupId(createEvent.getGroupBo().getGroupId());
        chatEventBO.setGroupType(2);
        chatEventService.addEvent(chatEventBO);
    }


    /**
     * 删除群组监听器
     * @param groupDeleteEvent
     */
    @Transactional
    @EventListener(GroupDeleteEvent.class)
    public void deleteGroup(GroupDeleteEvent groupDeleteEvent) {
        GroupBo groupBo = groupDeleteEvent.getGroupBo();
        chatGroupService.deleteGroup(groupBo.getOwnerId(),groupBo.getGroupId());
    }

    /**
     * 修改群组信息监听器
     * @param updateGroupEvent
     */
    @Transactional
    @EventListener(UpdateGroupEvent.class)
    public void updateGroup(UpdateGroupEvent updateGroupEvent){
        GroupBo groupBo = updateGroupEvent.getGroupBo();
        chatGroupService.updateGroup(groupBo.getOwnerId(),groupBo.getGroupId(),groupBo.getGroupName());
    }

    /**
     * 批准加入群组监听器
     * @param memberJoinAgreementEvent
     */
    @Transactional
    @EventListener(MemberJoinAgreementEvent.class)
    public void memberJoinAgreement(MemberJoinAgreementEvent memberJoinAgreementEvent){
        ArrayList<ChatUserGroupBO> chatUserGroupBOS = new ArrayList<>();
        ChatUserGroupBO chatUserGroupBO = new ChatUserGroupBO();
        chatUserGroupBO.setGroupId(memberJoinAgreementEvent.getGroupId());
        chatUserGroupBO.setUserId(memberJoinAgreementEvent.getUserId());
        chatUserGroupBO.setPermission(1);
        chatUserGroupBOS.add(chatUserGroupBO);
        chatUserGroupService.saveBatch(chatUserGroupBOS);
        //成人批准进群事件
        ChatEventBO chatEventBO = new ChatEventBO();
        chatEventBO.setEventType(25);
        chatEventBO.setEventDetail(memberJoinAgreementEvent.getUserId()+ "joined" + memberJoinAgreementEvent.getGroupId());
        chatEventBO.setSourceId(memberJoinAgreementEvent.getOwnerId());
        chatEventBO.setTargetUserId(memberJoinAgreementEvent.getUserId());
        chatEventBO.setTargetGroupId(memberJoinAgreementEvent.getGroupId());
        chatEventBO.setGroupType(2);
        chatEventService.addEvent(chatEventBO);
    }

    /**
     * 离开群组监听器
     * @param memberLeaveGroupEvent
     */
    @Transactional
    @EventListener(MemberLeaveGroupEvent.class)
   public void memberLeaveGroupEvent(MemberLeaveGroupEvent memberLeaveGroupEvent){
        List<ChatUserGroupBO> byUserIdAndGroup = chatUserGroupService.findByUserIdAndGroup(memberLeaveGroupEvent.getGroupId(), memberLeaveGroupEvent.getUserId());
        if(CollectionUtil.isNotEmpty(byUserIdAndGroup)) {
            List<ChatUserGroupBO> collect = byUserIdAndGroup.stream().filter(o -> o.getPermission().equals(1)).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(collect)){
                ChatUserGroupBO chatUserGroupBO = collect.get(0);
                chatUserGroupBO.setPermission(3);
                chatUserGroupService.updateById(chatUserGroupBO);
            }
            //退群事件
            ChatEventBO chatEventBO = new ChatEventBO();
            chatEventBO.setEventType(26);
            chatEventBO.setEventDetail(memberLeaveGroupEvent.getUserId() + "leave out" + memberLeaveGroupEvent.getGroupId());
            chatEventBO.setGroupType(2);
            chatEventBO.setTargetGroupId(memberLeaveGroupEvent.getGroupId());
            chatEventBO.setSourceId(memberLeaveGroupEvent.getUserId());
            chatEventService.addEvent(chatEventBO);
        }
    }

    /**
     * 群组踢人事件
     * @param deleteGroupMemberEvent
     */
    @Transactional
    @EventListener(DeleteGroupMemberEvent.class)
    public void deleteGroupMemberEvent(DeleteGroupMemberEvent deleteGroupMemberEvent){
        List<ChatUserGroupBO> byUserIdAndGroup = chatUserGroupService.findByUserIdAndGroup(deleteGroupMemberEvent.getGroupBo().getGroupId(), deleteGroupMemberEvent.getUserId());
        if(CollectionUtil.isNotEmpty(byUserIdAndGroup)){
            List<ChatUserGroupBO> collect = byUserIdAndGroup.stream().filter(o -> o.getPermission().equals(1)).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)){
                ChatUserGroupBO chatUserGroupBO = collect.get(0);
                chatUserGroupBO.setPermission(3);
                chatUserGroupService.updateById(chatUserGroupBO);
                //群组踢人事件
                ChatEventBO chatEventBO = new ChatEventBO();
                chatEventBO.setEventType(27);
                chatEventBO.setEventDetail(deleteGroupMemberEvent.getOperationUserId()+ "delete" + deleteGroupMemberEvent.getUserId() + "from" + deleteGroupMemberEvent.getGroupBo().getGroupId());
                chatEventBO.setGroupType(2);
                chatEventBO.setTargetGroupId(deleteGroupMemberEvent.getGroupBo().getGroupId());
                chatEventBO.setSourceId(deleteGroupMemberEvent.getOperationUserId());
                chatEventBO.setTargetUserId(deleteGroupMemberEvent.getUserId());
                chatEventService.addEvent(chatEventBO);
            }

        }
    }


    /**
     * todo 未完成申请加群，本期暂不需要
     *
     *申请加入群组事件
     * @param memberJoinApplyEvent
     */
    @Transactional
    @EventListener(MemberJoinApplyEvent.class)
    public void memberJoinApplyEvent(MemberJoinApplyEvent memberJoinApplyEvent){
        //申请进群，但是未被同意
        //查询关联表里是否有记录
        List<ChatUserGroupBO> byUserIdAndGroup = chatUserGroupService.findByUserIdAndGroup(memberJoinApplyEvent.getGroupId(), memberJoinApplyEvent.getUserId());
        if (CollectionUtil.isEmpty(byUserIdAndGroup)){
            ArrayList<ChatUserGroupBO> chatUserGroupBOS = new ArrayList<>();
            ChatUserGroupBO chatUserGroupBO = new ChatUserGroupBO();
            chatUserGroupBO.setUserId(memberJoinApplyEvent.getUserId());
            chatUserGroupBO.setGroupId(memberJoinApplyEvent.getGroupId());
            chatUserGroupBO.setPermission(0);
            chatUserGroupBOS.add(chatUserGroupBO);
            chatUserGroupService.saveBatch(chatUserGroupBOS);
        }else {
            List<ChatUserGroupBO> collect = byUserIdAndGroup.stream().filter(o -> o.getPermission().equals(1)).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)){
                ChatUserGroupBO chatUserGroupBO = collect.get(0);
                chatUserGroupBO.setPermission(0);
                chatUserGroupService.updateById(chatUserGroupBO);
            }
        }

        //添加申请入群事件
        ChatEventBO chatEventBO = new ChatEventBO();
        chatEventBO.setEventType(24);
        chatEventBO.setEventDetail( memberJoinApplyEvent.getUserId() + "apply join" + memberJoinApplyEvent.getGroupId());
        chatEventBO.setGroupType(2);
        chatEventBO.setTargetGroupId(memberJoinApplyEvent.getGroupId());
        chatEventBO.setSourceId(memberJoinApplyEvent.getUserId());
        chatEventService.addEvent(chatEventBO);

    }
}
